package com.incross.dawin.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.regex.Pattern;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Debug;
import android.telephony.TelephonyManager;
import android.text.ClipboardManager;
import android.util.DisplayMetrics;
import android.widget.Toast;

public class CommonUtils {
	private static String PREFERENCE_KEY = "common_info";
	
	static final Charset dawinCharset = Charset.forName("UTF-8");
	static final String dawinEncoding = dawinCharset.name();
	
	public static final int KAKAO_TALK = 4444;
	public static final int KAKAO_STORY = 4445;
	
	// Density identifier
	public static final int DENSITY_LDPI = 159;
	public static final int DENSITY_MDPI = 160;
	public static final int DENSITY_HDPI = 240;
	public static final int DENSITY_XHDPI = 320;
	public static final int DENSITY_XXHDPI = 400;
	public static final int DENSITY_SXHDPI = 480;
	
	// device type decided. it decided by has call function or not.
	public static final int DEVICE_TYPE_PHONE = 1000;
	public static final int DEVICE_TYPE_TABLET = 1100;
	
	public static void setStringPreference(Context context, String key, String value) {
		SharedPreferences pref = context.getSharedPreferences(PREFERENCE_KEY, Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = pref.edit();
		
		editor.putString(key, value);
		editor.commit();
		
	}
	
	public static String getStringPreference(Context context, String key) {
		SharedPreferences pref = context.getSharedPreferences(PREFERENCE_KEY, Context.MODE_PRIVATE);
		return pref.getString(key, "");
	}
	
	public static void setIntPreference(Context context, String key, int value) {
		SharedPreferences pref = context.getSharedPreferences(PREFERENCE_KEY, Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = pref.edit();
		
		editor.putInt(key, value);
		editor.commit();
		
	}
	
	public static int getIntPreference(Context context, String key) {
		SharedPreferences pref = context.getSharedPreferences(PREFERENCE_KEY, Context.MODE_PRIVATE);
		return pref.getInt(key, -1);
	}
	
	public static ProgressDialog getProgressDialogWithMessage(Context context, String message, boolean isCancelable) {
		ProgressDialog dialog = new ProgressDialog(context);
		dialog.setMessage(message);
		dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		dialog.setCancelable(isCancelable);
		return dialog;
	}
	
	public static int getOrientation(Context context) {
		int currentOrientation = context.getResources().getConfiguration().orientation;
		return currentOrientation;
	}
	
	public static ScreenSize getScreenSize(Context context) {
		
		DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
	    int width = displayMetrics.widthPixels;
    	int height = displayMetrics.heightPixels;
    	
    	return new ScreenSize(width, height);
	}
	
	public static boolean isNumber(String src) {
		return Pattern.matches("^[0-9]*$", src);
	}
	
	public static AlertDialog getAlertDialog(Context context, String title, String message, String positiveButtonTitle, String negativeButtonTitle, 
			DialogInterface.OnClickListener positiveListener, DialogInterface.OnClickListener negativeListener) {
		
		AlertDialog.Builder dialog = new AlertDialog.Builder(context);
		
		dialog.setTitle(title);
		dialog.setMessage(message);
		
		if(positiveButtonTitle != null && !positiveButtonTitle.equals("")) {
			dialog.setPositiveButton(positiveButtonTitle, positiveListener);
		}
		
		if(negativeButtonTitle != null && !negativeButtonTitle.equals("")) {
			dialog.setNegativeButton(negativeButtonTitle, negativeListener);
		}
		
		return dialog.create();
	}
	
	public static void callTo(Context context, String number) {
		if(context != null) {
			if(number != null && !number.equals("")) {
				context.startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number)));
			}
		}
	}
	
	public static int getGreatestCommonMeasure(int num1, int num2) {
		if(num1 < 1) {
			return -1;
		}
		
		int one, two;
		if(num1 > num2) {
			one = num1;
			two = num2;
		} else {
			one = num2;
			two = num1;
		}
		
		int temp;      // 임시변수를 저장할 공간
		while(true){     // 조건에 맞지 않는 동안 반복
			temp = one % two; // 두수를 나눈 나머지가 
			if(temp == 0){
				break;
			} else {
				one=two;
				two=temp;
			}
		}
		
		return two;
		
	}
	
	
	public static int getDeviceType(Context context) {
		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		String phoneNum = tm.getLine1Number();
		int type = tm.getPhoneType();
		
		BKLog.d("CommonUtils", "phoneNum : " + phoneNum + ", type : " + type);
		
		if(tm != null && type == TelephonyManager.PHONE_TYPE_NONE) {
			return DEVICE_TYPE_PHONE;
		} else {
			return DEVICE_TYPE_TABLET;
		}
	}
	
	public static String readTextFile(String path) {
		String result = null;
		
		FileInputStream fis;
		
		int size = 0;
		File file = new File(path);
		try {
			fis = new FileInputStream(file);
			size = fis.available();
			byte[] buffer = new byte[size];
			fis.read(buffer);
			
			result = new String(buffer);
			
			fis.close();
		} catch(IOException e) {
			BKLog.w("SavedFile not found..");
		}
		
		return result;
	}
	
	public static void showMemoryStatusLog() {
		double maxMemory = Runtime.getRuntime().maxMemory() / ( 1024.0f );
		double allocateMemory = Debug.getNativeHeapAllocatedSize() / ( 1024.0f );
		BKLog.i("최대 메모리 : " + maxMemory + "KB ");
		BKLog.i("사용 메모리 : " + allocateMemory + "KB");
	}
	
	public static void showNativeMemoryStatus() {
		BKLog.i("------------------- Memory Status");
		BKLog.i("Native Heap size : " + (Debug.getNativeHeapSize() / 1024.0f) + "KB");
		BKLog.i("Native Heap free size : " + (Debug.getNativeHeapFreeSize() / 1024.0f) + "KB");
		BKLog.i("Native Heap allocated size : " + (Debug.getNativeHeapAllocatedSize() / 1024.0f) + "KB");
	}
	
	public static boolean canMakeCall(Context context) {
		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		int type = tm.getPhoneType();
		if(tm != null) {
			String phoneNum = tm.getLine1Number();
			if(phoneNum != null) {
				BKLog.i("Phone number : " + phoneNum);
				if(type == TelephonyManager.PHONE_TYPE_CDMA || type == TelephonyManager.PHONE_TYPE_GSM) {
					return true;
				} else {
					return false;
				}
			} else {
				BKLog.e("Phone number null!!!");
				return false;
			}
			
		} else {
			return false;
		}
		
		/*PackageManager pac = context.getPackageManager();
		
		Uri callUri = Uri.parse("tel:");
		Intent callIntent = new Intent(Intent.ACTION_CALL, callUri);
		
		List<ResolveInfo> list = pac.queryIntentActivities(callIntent, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
		ArrayList<ActivityInfo> tempList = new ArrayList<ActivityInfo>();
		
		int count = list.size();
		String packageName = "";
		
		for(int i = 0; i < count; i++) {
			ResolveInfo firstInfo = list.get(i);
			packageName = firstInfo.activityInfo.applicationInfo.packageName;
			tempList.add(list.get(i).activityInfo);
			Log.i("BenTag", "Package name = " + packageName);
		}
		
		if(packageName == null || packageName.equals("")) {
			return false;
		} else {
			return true;
		}*/
		
		
		
	}
	
	public static int setTextToPrimaryClipboard(Context context, String text, String toastMsg) {
		if(context == null || text == null || text.equals("")) {
			return -1;
		}
		int sdk = android.os.Build.VERSION.SDK_INT;
		BKLog.w("------------- clipboard!!");
		if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
		    android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
		    clipboard.setText(text);
		} else {
		    android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); 
		    android.content.ClipData clip = android.content.ClipData.newPlainText("DawinShare", text);
		    clipboard.setPrimaryClip(clip);
		}
		
		ClipboardManager clipManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
		
		clipManager.setText(text);
		if(toastMsg != null && !toastMsg.equals("")) {
			Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show();
		}
		return 0;
	}
	
	public static void shareKakao(Context context, int kakaoType, String title, String message, String shareUrl) throws UnsupportedEncodingException {
		// Context가 없거나, 카카오 타입이 없는경우는 비정상적인 상황으로 보고 종료함.
		if(context == null) return;
		if(kakaoType != KAKAO_STORY && kakaoType != KAKAO_TALK) return;
		
		String nextContent = "\n";
		
		StringBuilder content = new StringBuilder();
		
		if(title != null && !title.equals("")) {
			content.append(title).append(nextContent);
		}
		
		if(message != null && !message.equals("")) {
			content.append(message).append(nextContent);
		}
		
		if(shareUrl != null && !shareUrl.equals("")) {
			content.append(shareUrl);
			content.append("\n");
		}
		
		switch(kakaoType) {
			case KAKAO_TALK:
				StringBuilder sb = new StringBuilder("kakaolink://sendurl?");
				sb.append("&msg=").append(URLEncoder.encode(content.toString(), dawinEncoding));
				sb.append("&appid=").append(URLEncoder.encode("1", dawinEncoding));
				sb.append("&appver=").append(URLEncoder.encode("1", dawinEncoding));
				
				BKLog.e("######## " + sb.toString());
				Intent talkIntent = new Intent(Intent.ACTION_SEND, Uri.parse(sb.toString()));
				
				context.startActivity(talkIntent);
				break;
				
			case KAKAO_STORY:
				Intent intent = context.getPackageManager().getLaunchIntentForPackage("com.kakao.story");
				intent.putExtra(Intent.EXTRA_TEXT, content.toString());
				intent.setType("text/plain");
		        context.startActivity(intent);
				break;
		}
		
	}
	
	
	public static void startApplication(Context context, String Package) {
		Intent intent = context.getPackageManager().getLaunchIntentForPackage(Package);  // packageName
		context.startActivity(intent);
	}
	
	/**
	 * gets device's density DPI.
	 * @param context : application's context
	 * @return : 320 or bigger xhdpi, 240 to 320 hdpi, 160 to 240 mdpi, ldpi under 160(120)
	 */
	public static int getDensityDpi(Context context) {
		DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
		return displayMetrics.densityDpi;
	}
	
	/**
	 * get device's density.
	 * @param context : application's context
	 * @return : returns one of defined variables in CommonUtils.
	 * @see CommonUtils
	 */
	
	public static int getDensity(Context context) {
		int densityDpi = CommonUtils.getDensityDpi(context);
		if(densityDpi < 160) { // ldpi
			return DENSITY_LDPI;
		} else if(densityDpi >= 160 && densityDpi < 240) { // mdpi
			return DENSITY_MDPI;
		} else if(densityDpi >= 240 && densityDpi < 320) { // hdpi
			return DENSITY_HDPI;
		} else if(densityDpi >= 320 && densityDpi < 400) { // xhdpi
			return DENSITY_XHDPI;
		} else if(densityDpi >= 400 && densityDpi < 480) { // xxhdpi
			return DENSITY_XXHDPI;
		} else if(densityDpi >= 480) { // sxhdpi
			return DENSITY_SXHDPI;
		} else {
			return DENSITY_XHDPI;
		}
	}
	
	public static boolean isPackageInstalled(Context context, String packageName) {
		boolean result = true;
		PackageManager pm = context.getPackageManager();
		try {
			PackageInfo pi = pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
		} catch (NameNotFoundException e) {
			// 패키지 정보를 찾을 수 없는경우 예외가 떨어진다.
			e.printStackTrace();
			result = false;
		}
		return result;
	}
	
	public static class ScreenSize {
		private int mWidth, mHeight;
		
		public ScreenSize(int width, int height) {
			mWidth = width;
			mHeight = height;
		}
		
		public int getWidth() {
			return mWidth;
		}
		
		public int getHeight() {
			return mHeight;
		}
	}
	
}
